package subcommands

import (
	"fmt"
	"rc/logger"
	"rc/remote"
	"rc/remote/param"
	"rc/repo"
	"rc/repo/model"
	"rc/utils"
	"time"

	flags "github.com/jessevdk/go-flags"
	"github.com/urfave/cli"
)

func PutCli(c *cli.Context) error {
	return putByNodes(c.String("n"),
		c.String("g"),
		c.String("u"),
		c.String("f"),
		c.String("t"))
}

// Put get command
func Put(args []string) error {
	var (
		err error
		log = logger.GetLogger()
	)

	// opts for put subcommand
	var opts struct {
		Group string `short:"g" long:"group" description:"group name"`
		Node  string `short:"n" long:"node" description:"node name"`
		User  string `short:"u" long:"user" description:"user for put file, default is the node's first user info"`
		From  string `short:"f" long:"from" description:"local file path" required:"true"`
		To    string `short:"t" long:"to" description:"remote file path" required:"true"`
	}

	var parser = flags.NewParser(&opts, flags.HelpFlag|flags.PassDoubleDash)
	parser.Command.Name = "put" // set current command name
	_, err = parser.ParseArgs(args)
	if err != nil {
		if err.(*flags.Error).Type == flags.ErrHelp {
			fmt.Println(err.Error())
			return nil
		}
		log.Debug("parser error : %#v\n", err)
		return err
	}
	log.Debug("opts: %v\n", opts)

	return putByNodes(opts.Node, opts.Group, opts.User, opts.From, opts.To)
}

func putByNodes(nodeName, groupName, userName, fromPath, toPath string) error {
	var (
		err       error
		localPath string
		r         repo.Repo
		re        remote.Remote
		userInfo  model.UserInfo
		nodes     []model.Node
		results   []*param.RcpOutput
		log       = logger.GetLogger()
	)

	// get nodes for get command
	r = repo.GetRepo()
	if r == nil {
		return fmt.Errorf("may be repo is empty, default repo is : ~/.rc.json")
	}

	nodes, err = r.GetNodes(nodeName, groupName)
	if err != nil {
		return err
	}
	log.Debug("nodes: %#v\n", nodes)

	if userInfo, err = validateUserParam(nodes, userName); err != nil {
		return err
	}

	// get command
	results = make([]*param.RcpOutput, 0)
	var rcpStart = time.Now()
	for _, n := range nodes {
		fmt.Printf("%s(%s):\n", utils.FgBoldGreen(n.Name), utils.FgBoldGreen(n.IPv4))
		re = remote.New(userInfo.UserName, userInfo.Password, userInfo.KeyPath, n.IPv4, n.Port)

		// display result
		localPath, err = utils.ConvertHomeDir(fromPath)
		if err != nil {
			return err
		}
		output := re.Put(localPath, toPath)
		displayRcpResult(output)
		results = append(results, output)
	}
	displayTotalRcpResult(results, rcpStart, time.Now())
	return nil
}
